home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / misc / sci / ephem_src_4_28.lha / listing.c < prev    next >
C/C++ Source or Header  |  1992-05-24  |  8KB  |  340 lines

  1. /* code to support the listing capabilities.
  2.  * idea is to let the operator name a listing file and mark some fields for
  3.  * logging. then after each screen update, the logged fields are written to
  4.  * the listing file in the same manner as they appeared on the screen.
  5.  * 
  6.  * format of the listing file is one line per screen update.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include "screen.h"
  12.  
  13. extern char *strcpy();
  14.  
  15. #ifdef VMS
  16. #include <perror.h>
  17. #include <errno.h>
  18. #else
  19. extern char *sys_errlist[];
  20. extern errno;
  21. #endif
  22.  
  23. #define    errsys    (sys_errlist[errno])
  24.  
  25.  
  26. #define    TRACE(x)    {FILE *fp = fopen("trace","a"); fprintf x; fclose(fp);}
  27.  
  28. #define    MAXLSTFLDS    10    /* max number of fields we can track.
  29.                  * note we can't store more than NFLOGS fields
  30.                  * anyway (see flog.c).
  31.                  */
  32. #ifdef AMIGA
  33. #define    FNLEN        (30+1)    /* longest filename; plus 1 for \0 */
  34. #else
  35. #define    FNLEN        (14+1)    /* longest filename; plus 1 for \0 */
  36. #endif
  37.  
  38. static char lst_filename[FNLEN] = "ephem.lst";    /* default plot file name */
  39. static FILE *lst_fp;        /* the plot file; == 0 means don't plot */
  40.  
  41. /* store rcfpack()s for each field to track, in l-to-r order */
  42. static int lstflds[MAXLSTFLDS];
  43. static int nlstflds;        /* number of lstflds[] in actual use */
  44.  
  45. static int lstsrchfld;        /* set when the Search field is to be listed */
  46.  
  47. /* picked the Listing label:
  48.  * if on, just turn it off.
  49.  * if off, turn on, define fields or select name of file to list to and do it.
  50.  * TODO: more flexibility, more relevance.
  51.  */
  52. listing_setup()
  53. {
  54.     if (lst_fp)
  55.         lst_turn_off();
  56.     else {
  57.         static char *chcs[] = {
  58.         "Select fields", "Display a listing file", "Begin listing"
  59.         };
  60.         static int fn;    /* start with 0, then remember for next time */
  61.     ask:
  62.         switch (popup(chcs, fn, nlstflds > 0 ? 3 : 2)) {
  63.         case 0: fn = 0; lst_select_fields(); goto ask;
  64.         case 1: fn = 1; lst_file(); goto ask;
  65.         case 2: fn = 2; lst_turn_on(); break;
  66.         default: break;
  67.         }
  68.     }
  69. }
  70.  
  71. /* write the active listing to the current listing file, if one is open. */
  72. listing()
  73. {
  74.     if (lst_fp) {
  75.         int n;
  76.         double flx;
  77.         char flstr[32];
  78.         if (!srch_ison() && lstsrchfld) {
  79.         /* if searching is not on but we are listing the search
  80.          * funtion we must evaluate and log it ourselves here and now.
  81.          * lst_turn_on() insured there is a good function to eval.
  82.          * N.B. if searching IS on, we rely on main() having called
  83.          * srch_eval() BEFORE plot() so it is already evaluated.
  84.          */
  85.         double e;
  86.         char errmsg[128];
  87.         if (execute_expr (&e, errmsg) < 0) {
  88.             f_msg (errmsg);
  89.             lst_turn_off();
  90.             return;
  91.         } else {
  92.             (void) sprintf (flstr, "%g", e);
  93.             (void) flog_log (R_SRCH, C_SRCH, e, flstr);
  94.         }
  95.         }
  96.  
  97.         /* list in order of original selection */
  98.         for (n = 0; n < nlstflds; n++)
  99.         if (flog_get (lstflds[n], &flx, flstr) == 0)
  100.             (void) fprintf (lst_fp, "%s  ", flstr);
  101.         (void) fprintf (lst_fp, "\n");
  102.     }
  103. }
  104.  
  105. listing_prstate (force)
  106. int force;
  107. {
  108.     static last;
  109.     int this = lst_fp != 0;
  110.  
  111.     if (force || this != last) {
  112.         f_string (R_LISTING, C_LISTINGV, this ? " on" : "off");
  113.         last = this;
  114.     }
  115. }
  116.  
  117. listing_ison()
  118. {
  119.     return (lst_fp != 0);
  120. }
  121.  
  122. static
  123. lst_reset()
  124. {
  125.     int *lp;
  126.  
  127.     for (lp = lstflds; lp < &lstflds[nlstflds]; lp++) {
  128.         (void) flog_delete (*lp);
  129.         *lp = 0;
  130.     }
  131.     nlstflds = 0;
  132.     lstsrchfld = 0;
  133. }
  134.  
  135. /* let operator select the fields he wants to have in his listing.
  136.  * register them with flog and keep rcfpack() in lstflds[] array.
  137.  * as a special case, set lstsrchfld if Search field is selected.
  138.  */
  139. static
  140. lst_select_fields()
  141. {
  142.     static char hlp[] = "move and RETURN to select a field, or q to quit";
  143.     static char sry[] = "Sorry; can not list any more fields.";
  144.     int f = rcfpack(R_UT,C_UTV,0); /* TODO: start where main was? */
  145.     int sf = rcfpack (R_SRCH,C_SRCH,0);
  146.     char buf[64];
  147.     int i;
  148.  
  149.     lst_reset();
  150.     for (i = 0; i < MAXLSTFLDS; i++) {
  151.         (void) sprintf(buf,"select field for column %d or q to quit", i+1);
  152.         f = sel_fld (f, alt_menumask()|F_PLT, buf, hlp);
  153.         if (!f)
  154.         break;
  155.         if (flog_add (f) < 0) {
  156.         f_msg (sry);
  157.         break;
  158.         }
  159.         lstflds[i] = f;
  160.         if (f == sf)
  161.         lstsrchfld = 1;
  162.     }
  163.     if (i == MAXLSTFLDS)
  164.         f_msg (sry);
  165.     nlstflds = i;
  166. }
  167.  
  168. static
  169. lst_turn_off ()
  170. {
  171.     (void) fclose (lst_fp);
  172.     lst_fp = 0;
  173.     listing_prstate(0);
  174. }
  175.  
  176. /* turn on listing facility.
  177.  * establish a file to use (and thereby set lst_fp, the "listing-is-on" flag).
  178.  * also check that there is a srch function if it is being used.
  179.  */
  180. static
  181. lst_turn_on ()
  182. {
  183.     int sf = rcfpack(R_SRCH, C_SRCH, 0);
  184.     char fn[FNLEN], fnq[NC];
  185.     char *optype;
  186.     int n;
  187.  
  188.     /* insure there is a valid srch function if we are to list it */
  189.     for (n = 0; n < nlstflds; n++)
  190.         if (lstflds[n] == sf && !prog_isgood()) {
  191.         f_msg ("Listing search function but it is not defined.");
  192.         return;
  193.         }
  194.  
  195.     /* prompt for file name, giving current as default */
  196.     (void) sprintf (fnq, "file to write <%s>: ", lst_filename);
  197.     f_prompt (fnq);
  198.     n = read_line (fn, sizeof(fn)-1);
  199.  
  200.     /* leave plotting off if type END.
  201.      * reuse same fn if just type \n
  202.      */
  203.     if (n < 0)
  204.         return;
  205.     if (n > 0)
  206.         (void) strcpy (lst_filename, fn);
  207.  
  208.     /* give option to append if file already exists */
  209.     optype = "w";
  210.     if (access (lst_filename, 2) == 0) {
  211.         while (1) {
  212.         f_prompt ("files exists; append or overwrite (a/o)?: ");
  213.         n = read_char();
  214.         if (n == 'a') {
  215.             optype = "a";
  216.             break;
  217.         }
  218.         if (n == 'o')
  219.             break;
  220.         }
  221.     }
  222.  
  223.     /* listing is on if file opens ok */
  224.     lst_fp = fopen (lst_filename, optype);
  225.     if (!lst_fp) {
  226.         (void) sprintf (fnq, "can not open %s: %s", lst_filename, errsys);
  227.         f_msg (fnq);
  228.     } else {
  229.         /* add a title if desired */
  230.         static char tp[] = "Title (q to skip): ";
  231.         f_prompt (tp);
  232.         if (read_line (fnq, PW - sizeof(tp)) > 0)
  233.         (void) fprintf (lst_fp, "%s\n", fnq);
  234.     }
  235.  
  236.     listing_prstate (0);
  237. }
  238.  
  239. /* ask operator for a listing file to show. if it's ok, do it.
  240.  */
  241. static
  242. lst_file ()
  243. {
  244.     char fn[FNLEN], fnq[64];
  245.     FILE *lfp;
  246.     int n;
  247.  
  248.     /* prompt for file name, giving current as default */
  249.     (void) sprintf (fnq, "file to read <%s>: ", lst_filename);
  250.     f_prompt (fnq);
  251.     n = read_line (fn, sizeof(fn)-1);
  252.  
  253.     /* forget it if type END.
  254.      * reuse same fn if just type \n
  255.      */
  256.     if (n < 0)
  257.         return;
  258.     if (n > 0)
  259.         (void) strcpy (lst_filename, fn);
  260.  
  261.     /* show it if file opens ok */
  262.     lfp = fopen (lst_filename, "r");
  263.     if (lfp) {
  264.         display_listing_file (lfp);
  265.         (void) fclose (lfp);
  266.     } else {
  267.         char buf[NC];
  268.         (void) sprintf (buf, "can not open %s: %s", lst_filename, errsys);
  269.         f_prompt (buf);
  270.         (void)read_char();
  271.     }
  272. }
  273.  
  274. /* display the given listing file on the screen.
  275.  * allow for files longer than the screen.
  276.  * N.B. do whatever you like but redraw the screen when done.
  277.  */
  278. static
  279. display_listing_file (lfp)
  280. FILE *lfp;
  281. {
  282.     static char eofp[] = "[End-of-file. Hit any key to resume...] ";
  283.     static char p[] =    "[Hit any key to continue or q to quit...] ";
  284.     char buf[NC+2];    /* screen width plus for '\n' and '\0' */
  285.     int nc, nl;
  286.  
  287.     c_erase();
  288.  
  289.     nl = 0;
  290.     while (1) {
  291.         (void) fgets (buf, sizeof(buf), lfp);
  292.         if (feof(lfp)) {
  293. #ifdef AMIGA
  294.         cwrite(eofp);
  295. #else
  296.         printf (eofp);
  297. #endif
  298.         (void) read_char();
  299.         break;
  300.         }
  301.         /* make sure last char is \n, even if it's a long line */
  302.         nc = strlen (buf);
  303.         if (nc == NC+1) {
  304.         (void) ungetc (buf[NC], lfp);
  305.         buf[NC] = '\n';
  306.         }
  307. #ifdef AMIGA
  308.         cwrite(buf);
  309.         cwrite("\r");
  310. #else
  311.         printf ("%s\r", buf);
  312. #endif
  313.         if (++nl == NR-1) {
  314.         /* read-ahead one char to check for eof */
  315.         int rach = getc (lfp);
  316.         if (feof(lfp)) {
  317. #ifdef AMIGA
  318.             cwrite(eofp);
  319. #else
  320.             (void) printf (eofp);
  321. #endif
  322.             (void) read_char();
  323.             break;
  324.         } else
  325.             (void) ungetc (rach, lfp);
  326. #ifdef AMIGA
  327.         cwrite(p);
  328. #else
  329.         (void) printf (p);
  330. #endif
  331.         if (read_char() == END)
  332.             break;
  333.         c_erase();
  334.         nl = 0;
  335.         }
  336.     }
  337.  
  338.     redraw_screen (2);    /* full redraw */
  339. }
  340.